﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using log4net;
using NHibernate;
using TeamCommunitySolution.Domain.DataLayer.Leagues;
using TeamCommunitySolution.Services.Factories;

namespace TeamCommunitySolution.Services.Repositories.Impl
{
    /// <summary>
    /// Implementation of the League Repository Interface
    /// </summary>
    public class LeagueRepository : ILeagueRepository
    {
        /// <summary>
        /// Logger instance.
        /// </summary>
        private static readonly ILog _log = LogManager.GetLogger(typeof(LeagueRepository));

        /// <summary>
        /// The repository instance.
        /// </summary>
        private static ILeagueRepository _repo = null;

        /// <summary>
        /// Prevents a default instance of the <see cref="LeagueRepository"/> class from being created.
        /// </summary>
        private LeagueRepository()
        {
        }

        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>The instance.</value>
        public static ILeagueRepository Instance
        {
            get
            {
                if (_repo == null)
                {
                    _repo = new LeagueRepository();
                }

                return _repo;
            }
        }
        #region ILeagueRepository Members

        /// <summary>
        /// Saves the league.
        /// </summary>
        /// <param name="league">The league.</param>
        public void SaveLeague(League league)
        {
            using (ISession session = NHSessionFactory.Factory.OpenSession())
            {
                var scope = session.BeginTransaction();

                try
                {
                    session.SaveOrUpdate(league);
                    scope.Commit();
                }
                catch (Exception ex)
                {
                    scope.Rollback();
                    string message = "Unable to save object [league] in datastore.";
                    this.HandleException(message, ex);
                }
            }
        }

        /// <summary>
        /// Gets the league.
        /// </summary>
        /// <param name="id">The id of the league.</param>
        /// <returns>A league instance.</returns>
        public League GetLeague(string id)
        {
            using (ISession session = NHSessionFactory.Factory.OpenSession())
            {
                try
                {
                    return session.Get<League>(id);
                }
                catch (Exception ex)
                {
                    string message = "Unable to find object [league] in datastore.";
                    this.HandleException(message, ex);
                }
            }

            return null;
        }

        /// <summary>
        /// Saves the league meeting.
        /// </summary>
        /// <param name="leagueMeeting">The league meeting.</param>
        public void SaveLeagueMeeting(LeagueMeeting leagueMeeting)
        {
            using (ISession session = NHSessionFactory.Factory.OpenSession())
            {
                var scope = session.BeginTransaction();

                try
                {
                    session.SaveOrUpdate(leagueMeeting);
                    scope.Commit();
                }
                catch (Exception ex)
                {
                    scope.Rollback();
                    string message = "Unable to save object [league meeting] in datastore.";
                    this.HandleException(message, ex);
                }
            }
        }

        /// <summary>
        /// Gets the league meeting.
        /// </summary>
        /// <param name="id">The id of the league meeting.</param>
        /// <returns>League meeting instance.</returns>
        public LeagueMeeting GetLeagueMeeting(string id)
        {
            using (ISession session = NHSessionFactory.Factory.OpenSession())
            {
                try
                {
                    return session.Get<LeagueMeeting>(id);
                }
                catch (Exception ex)
                {
                    string message = "Unable to find object [league meeting] in datastore.";
                    this.HandleException(message, ex);
                }
            }

            return null;
        }

        #endregion

        /// <summary>
        /// Handles the exception.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="ex">The exception.</param>
        private void HandleException(string message, Exception ex)
        {
            _log.Error(message, ex);
            throw new LeagueRepositoryException(message, ex);
        }
    }
}
